#include "EventLoopThreadPool.h"
#include "Channel.h"
#include "EventLoopThread.h"
#include "utils.h"
#include <cstdlib>
#include <memory>
#include <stdio.h>

namespace droneswarm
{

    EventLoopThreadPool::EventLoopThreadPool( EventLoop *baseLoop, int numThreads )
        : baseLoop_( baseLoop )
        , started_( false )
        , numThreads_( numThreads )
        , next_( 0 )
    {
        if ( numThreads_ <= 0 )
        {
            LOG << "numThreads_ <=0" << '\n';
            abort();  //这个函数用于退出程序
        }
    }

    EventLoopThreadPool::~EventLoopThreadPool() {}

    void EventLoopThreadPool::start()
    {
        //在我们的这个webserver服务器中，主事件循环和线程池运行在同一个线程中。
        baseLoop_->assertInLoopThread();
        started_ = true;
        //创建线程
        for ( int i = 0; i < numThreads_; ++i )
        {
            //首先这只是创建了EventLoopThread的对象并初始化了，
            /*
                thread_ --->(初始化)EventLoopThread::threadFuc--->ThreadFunc--->ThreadData.Func
                线程创建并执行顺序
                thread_.start--->pthread_create--->(线程创建)
                创建的线程：startThread--->ThreadData.runInThread--->ThreadData.Func
            */
            std::shared_ptr< EventLoopThread > t( new EventLoopThread() );
            //EventLoopThread绑定了线程。
            //将 EventLoopThread存放到线程池指针容器中
            threads_.push_back( t );
            //只有执行了startLoop才是创建了线程，在线程中会创建事件循环loop，并执行loop。
            //启动事件循环，并将EventLoop 指针存放到容器中进行管理。
            loops_.push_back( t->startLoop() );
        }
        //运行到这里，线程池中的线程创建成功并且线程也在执行loop并返回了EventLoop。
    }

    //这个函数的作用就是从EventLoop池中取出指定位置的EventLoop
    EventLoop *EventLoopThreadPool::getNextLoop()
    {
        baseLoop_->assertInLoopThread();
        CondPanic( started_, "started_ is false !!" );
        EventLoop *loop = baseLoop_;
        if ( !loops_.empty() )
        {
            loop = loops_[ next_ ];
            next_ = ( next_ + 1 ) % numThreads_;  // next的值不会超过numThreads_的值。
        }
        return loop;
    }
}  // namespace droneswarm